package com.shiguiwu.springmybatis.app.controller;

import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.api.R;

import com.shiguiwu.springmybatis.app.entity.User;
import com.shiguiwu.springmybatis.javabase.encrypt.RSAUtil;
import com.shiguiwu.springmybatis.javabase.encrypt.SignUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

/**
 * @description: 加密测试
 * @author: stone
 * @date: Created by 2022/9/18 14:56
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.app.controller
 */
@RestController
@RequestMapping("/scrypt")
@Slf4j
public class ScryptController {


    @Value("${rsa.private-key}")
    public String privateKey;



    @Value("${rsa.public-key}")
    public String publicKey;


    public static String getStringByInputStream(InputStream inputStream) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            byte[] b = new byte[10240];
            int n;
            while ((n = inputStream.read(b)) != -1) {
                outputStream.write(b, 0, n);
            }
        } catch (Exception e) {
            try {
                inputStream.close();
                outputStream.close();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
        return outputStream.toString();
    }

    /**
     * 获取请求体
     * @param request 请求
     * @return 请求体
     */
    private static String getBody(HttpServletRequest request) {
        try {
            ServletInputStream stream = request.getInputStream();


            return getStringByInputStream(stream);
        } catch (IOException e) {
            log.debug(e.getMessage());
            throw new RuntimeException(e);
        }
    }



    @PostMapping("/login")
    public R<?> login(HttpServletRequest request) {
        String body = getBody(request);

        log.info("s ===>:{}", body);

        //解密
        String decryptPrivateKey = RSAUtil.decryptPrivateKey(body, privateKey);

        User user = JSONUtil.toBean(decryptPrivateKey, User.class);
        log.info("请求体body ===> {}", JSONUtil.toJsonStr(user));
        String timestamp = request.getHeader("timestamp");
        log.info("时间戳 ===> {}", timestamp);

        String requestId = request.getHeader("requestId");

        log.info("请求id ===> {}", requestId);
        return R.ok(user);
    }


    @PostMapping("/v2/login")
    public R<?> login(@RequestBody  User user ) {

        log.info("s ===>:{}", JSONUtil.toJsonStr(user));

        //解密
        String decodePassword = RSAUtil.decryptPrivateKey(user.getPassword(), privateKey);
        String decodeUseruame = RSAUtil.decryptPrivateKey(user.getUsername(), privateKey);

        //User user = JSONUtil.toBean(decryptPrivateKey, User.class);
        user.setUsername(decodeUseruame);
        user.setPassword(decodePassword);

        log.info("请求体body ===> {}", JSONUtil.toJsonStr(user));
        //String timestamp = request.getHeader("timestamp");
        //        //log.info("时间戳 ===> {}", timestamp);

        //String requestId = request.getHeader("requestId");

        //log.info("请求id ===> {}", requestId);
        return R.ok(user);
    }

    @GetMapping("/sign")
    public R<?> detail(HttpServletRequest request) {
        Map<String, String> headerMap = ServletUtil.getParamMap(request);

        String sign = request.getHeader("sign");
        boolean f = SignUtil.verify(sign, headerMap, publicKey);
        if (Boolean.FALSE.equals(f)) {
            return R.failed("验签失败！");
        }

        return R.ok(request.toString());
    }


    @Data
    public static class Model {
        private String mode;

        private String raw;
    }



}
